//
//  YRNKBookmark.swift
//  YoruNeko
//
//  Created by  mahoPunch on 2021/6/25.
//

import Foundation

class YRNKBookmark:Hashable,Codable{
    static func == (lhs: YRNKBookmark, rhs: YRNKBookmark) -> Bool {
        return lhs.this == rhs.this
    }
    
    func hash(into hasher: inout Hasher) {
        this.hash(into: &hasher)
    }
    
    /*
     Bug: weak reference 如果这里使用了弱应用，则swift ARC 机制会因为没有强饮用至parent导致parent‘s ARC 为 0 时 ，为自动释放
     */
    var parent:YRNKBookmark?
    var this: Bookmark
    
    var children:[YRNKBookmark]?
    
    //根YRNKBookmark构造器
    init(){
        let date = Date()
        this = Bookmark(date_added: date, last_visited: date, name: "root")
        children = [YRNKBookmark].init()
    }
    
    //值拷贝构造器,新建书签类型
    init(reference to:Bookmark, parent:YRNKBookmark?, isDirectory:Bool){
        self.this = to
        
        self.parent = parent
        
//        YRNKLog("YRNKBookmark evaluate self.parent == nil", msg: (self.parent == nil).description)
//
//        YRNKLog("YRNKBookmark evaluate(self.parent == parent)", msg: (self.parent == parent).description)
        
        if self.parent != nil {
//            YRNKLog("YRNKBookmark evaluate self.parent.this.name", msg: self.parent!.this.name)
        }
        
        if isDirectory{
            children = [YRNKBookmark].init()
        }
    }
    
    var isDirectory:Bool{
        return children != nil
    }
    
    func editParent(parent: YRNKBookmark){
        self.parent = parent
    }
    
    func editBookmark(withName newName: String, andURL newURL: String){
        this.name = newName
        if !isDirectory{
            this.url = newURL
        }
        
    }
    
    func addChildren(children:[YRNKBookmark]){
        if self.isDirectory{
            
        }
    }
    
    func addChild(child:YRNKBookmark){

        if isDirectory {
            child.parent = self
            children?.append(child)
            
        }
    }
    
    func deleteChild(childId:UUID)->Bool {
        if isDirectory{
            if children!.firstIndex(where: {$0.this.id==childId}) != nil {
                children!.remove(at: (children!.firstIndex(where: {$0.this.id==childId}))!)
                return true
            }
            else{
                return false
            }
        }
        else {
            return false
        }
    }
    
    
    func deleteChildren(childrenIDs:[UUID])->Bool {
        return false
    }
    
    enum CodingKeys: String, CodingKey {
//        case parent
        case this
        case children
    }
    
    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        
        YRNKLog(this.id.uuidString ?? "", msg: "Encoding")
//        if let p = parent {
//            try container.encodeConditional(p, forKey: .parent)
//        }
        try container.encode(this, forKey: .this)
        try container.encodeIfPresent(children, forKey: .children)
        
    }
    
    required init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        self.this = try container.decode(Bookmark.self, forKey: .this)
        self.children = try container.decodeIfPresent([YRNKBookmark].self, forKey: .children)
    }
}
